package com.example.springbootdockerdemo.aspect;

import com.example.springbootdockerdemo.annotation.Authorized;
import com.example.springbootdockerdemo.exception.TongHuiException;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.mvc.condition.RequestConditionHolder;

import javax.servlet.http.HttpServletRequest;
import java.lang.annotation.Annotation;

/**
 * @ClassName AuthorizedAspect
 * @Author Chengy
 * @Date 2021/11/22 14:58
 * @Version 1.0
 */

@Aspect
@Component
@Slf4j
public class AuthorizedAspect {


    @Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping)")
    public void requestMapping() {
    }


    @Pointcut("execution(* com.example.springbootdockerdemo.controller.*.*(..))")
    public void methodPointcut() {
    }


    /**
     * 某个方法执行前进行请求合法性认证  注入Authorized注解(先)
     *
     * @param joinPoint
     * @param authorized
     */
    @Before("requestMapping() && methodPointcut() && @annotation(authorized)")
    public void doBefore(JoinPoint joinPoint, Authorized authorized) throws Exception {

        log.info("方法开始认证。。。");
        Class type = joinPoint.getSignature().getDeclaringType();

        Annotation[] annotations = type.getAnnotationsByType(Authorized.class);

        if (annotations != null && annotations.length > 0) {
            log.info("直接类认证");
            return;
        }

        //获取当前HTTP请求
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String token = request.getHeader("token");
        if ("123".equals(token)) {
            log.info("方法通过认证");
        } else {
            throw new TongHuiException(20001, "不存在此token：" + token);

        }

    }

    /**
     * 类下面所有方法执行前进行请求合法性认证 (后)
     *
     * @param joinPoint
     */
    @Before("requestMapping() && methodPointcut()")
    public void doBefore(JoinPoint joinPoint) throws Exception {

        log.info("类开始认证。。。");

        Annotation[] annotations = joinPoint.getSignature().getDeclaringType().getAnnotationsByType(Authorized.class);
        if (annotations == null && annotations.length == 0) {
            log.info("类不需要认证");
            return;
        }

        //获取当前HTTP请求
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String token = request.getHeader("token");
        if ("123".equals(token)) {
            log.info("类通过认证");
        } else {
            throw new TongHuiException(20001, "不存在此token：" + token);
        }

    }


}
